package unittest;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import multithread.framework.annotation.Param;
import multithread.framework.annotation.ThreadAfter;
import multithread.framework.annotation.ThreadAllAfter;
import multithread.framework.annotation.ThreadAllBefore;
import multithread.framework.annotation.ThreadBefore;
import multithread.framework.annotation.ThreadFor;
import multithread.framework.annotation.ThreadGroupAfter;
import multithread.framework.annotation.ThreadGroupBefore;
import multithread.framework.annotation.ThreadGroupFor;
import multithread.framework.threadmethod.ThreadMethod;
import multithread.framework.threadmethod.ThreadMethodParser;

public class extendsThreadMethodParse extends ThreadMethodParser{
	
	/**
	 * convert java.lang.reflect.Method to ThreadMethod, do not care validation
	 * 
	 * @param method
	 * @return ThreadMethod
	 */
	public ThreadMethod convertMethod(Method method) {
		Annotation[] annotations = method.getAnnotations();
		ThreadMethod threadMethod = new ThreadMethod(method);
		boolean isRunnerMethod = false;
		for (Annotation annotation : annotations) {
			if (annotation instanceof ThreadAllBefore) {
				threadMethod.setThreadAllBefor((ThreadAllBefore) annotation);
				isRunnerMethod = true;
			}
			if (annotation instanceof ThreadAllAfter) {
				threadMethod.setThreadAllAfter((ThreadAllAfter) annotation);
				isRunnerMethod = true;
			}
			if (annotation instanceof ThreadGroupBefore) {
				threadMethod
						.setThreadGroupBefore((ThreadGroupBefore) annotation);
				isRunnerMethod = true;
			}
			if (annotation instanceof ThreadGroupAfter) {
				threadMethod.setThreadGroupAfter((ThreadGroupAfter) annotation);
				isRunnerMethod = true;
			}
			if (annotation instanceof ThreadBefore) {
				threadMethod.setThreadBefor((ThreadBefore) annotation);
				isRunnerMethod = true;
			}
			if (annotation instanceof ThreadAfter) {
				threadMethod.setThreadAfter((ThreadAfter) annotation);
				isRunnerMethod = true;
			}
			if (annotation instanceof ThreadGroupFor) {
				threadMethod.setThreadGroupFor((ThreadGroupFor) annotation);
			}
			if (annotation instanceof ThreadFor) {
				threadMethod.setThreadFor((ThreadFor) annotation);
				isRunnerMethod = true;
			}
			// do not take method parameters expect ThreadFor method
			if (isRunnerMethod) {
				Object[] params = getMethodParams(method);
				threadMethod.setMethodParams(params);
			}
		}
		return threadMethod;
	}
	
	/**
	 * get test case method parameters
	 * 
	 * @param method
	 *            java.lang.reflect.Method
	 * @return
	 */
	public Object[] getMethodParams(Method method) {
		Annotation[][] annotations = method.getParameterAnnotations();
		Class<?>[] clzs = method.getParameterTypes();
		Object[] objs = new Object[clzs.length];
		for (int i = 0; i < clzs.length; i++) {
			Annotation annotation = annotations[i][0];
			Param paramAnotation = null;
			if (Param.class.isInstance(annotation)) {
				paramAnotation = (Param) annotation;
			}
			Class<?> clz = clzs[i];
			if (clz == String.class && paramAnotation != null) {
				objs[i] = (paramAnotation.value()[0]);
			} else if (clz.isPrimitive() && paramAnotation != null) {
				if (clz == int.class) {
					objs[i] = Integer.valueOf(paramAnotation.value()[0])
							.intValue();
				} else if (clz == long.class) {
					objs[i] = Long.valueOf(paramAnotation.value()[0])
							.longValue();
				} else if (clz == float.class) {
					objs[i] = Float.valueOf(paramAnotation.value()[0])
							.floatValue();
				} else if (clz == double.class) {
					objs[i] = Double.valueOf(paramAnotation.value()[0])
							.doubleValue();
				} else if (clz == boolean.class) {
					objs[i] = Boolean.valueOf(paramAnotation.value()[0])
							.booleanValue();
				} else if (clz == byte.class) {
					objs[i] = Byte.valueOf(paramAnotation.value()[0])
							.byteValue();
				} else if (clz == short.class) {
					objs[i] = Short.valueOf(paramAnotation.value()[0])
							.shortValue();
				} else if (clz == char.class) {
					objs[i] = paramAnotation.value()[0].charAt(0);
				}
			} else if (clz.isArray()) {
				objs[i] = paramAnotation.value();
			} else {
				objs[i] = null;
			}

		}
		return objs;
	}
}
